/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package reader;

import java.util.BitSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

/**
 *
 * @author Danzz
 */
public class Data {
    Header header;  // referen dari header/atribut2 yang sudah dibaca
    
    Vector<Map<String, Object>> arrayData;  // menyimpan semua data
    
    public Data(Header header) {
       this.header = header;
       arrayData = new Vector<Map<String, Object>>();
    }
    
    public void putData(String str) {
        String[] parse1 = str.split(",");
        Iterator iter = header.attrib.entrySet().iterator();
        int countIter = 0;
        Map mp = new LinkedHashMap<String, Object>();
        for (Map.Entry<String, DataType> mEntry : header.attrib.entrySet()) {
            String kunci = (String) mEntry.getKey();
            DataType dt = (DataType) mEntry.getValue();
            
            Boolean done = false;
            String parse2 = "";
            boolean bacaTerus = false;
            String quoteAwal = "";
            while(!done) {
                while (parse1[countIter].startsWith(" ") && !bacaTerus) {
                    parse1[countIter] = parse1[countIter].replaceFirst(" ", "");
                }
                if (parse1[countIter].startsWith("\"")  && !bacaTerus)
                    quoteAwal = "\"";
                else if (parse1[countIter].startsWith("'")  && !bacaTerus)
                    quoteAwal = "'";
                if(!quoteAwal.equals("") && parse1[countIter].endsWith(quoteAwal)  && !bacaTerus) {
                    parse2 = parse1[countIter].substring(1, parse1[countIter].length()-1);
                    done = true;
                } else if (quoteAwal.equals("") && !bacaTerus) {
                    parse2 = parse1[countIter];
                    done = true;
                } else if (bacaTerus) {
                    if (parse1[countIter].endsWith(quoteAwal)) {
                        parse2+=parse1[countIter].substring(0, parse1[countIter].length()-1);
                        done = true;
                    } else {
                        parse2+=parse1[countIter]+",";
                        bacaTerus = true;
                        countIter++;
                    }
                } else if (!bacaTerus) {
                    // berarti waktu split ada koma di dalam quote
                    bacaTerus = true;
                    parse2 += parse1[countIter].substring(1, parse1[countIter].length())+",";
                    countIter++;
                }
            }

            if (dt.dataType.equals(DataType.TypeEnum.numeric)) {
                // convert string ke numeric
                if (parse2.contains(".")) {
                    // bilangan real
                    mp.put(kunci, Float.parseFloat(parse2));
                } else { // integer
                    mp.put(kunci, Integer.parseInt(parse2));
                }
            } else {
                mp.put(kunci, parse2);
            }
            countIter++;
        }
        arrayData.add(mp);
    }
    
    public int getJumlahData() {
        return arrayData.size();
    }
    
    public int getJumlahDataSama(String bs) throws Exception {
        int maxValue = header.getMaxBit();
        // asumsi data nya semua nominal dulu yak!!!
        // transform data bitset ke vector nilai tiap atribut
        Vector<String> valueFromBitSet = new Vector<String>();
        int idxAttrib = 0;
        for (int i = 0;i< maxValue*header.getNumAttribute();i+=maxValue) {
            valueFromBitSet.add(header.getAttribValueAtIdx(idxAttrib, bitStringToInt(bs.substring(i, i+maxValue))));
            idxAttrib++;
        }
        
        // cocokan
        Vector<String> temp = new Vector<String>(); // temp untuk vector isi value tiap data
        int jumlah = 0;
        for (int i=0;i<arrayData.size();i++) {
            temp = getDataValue(i);
            int j = 0;
            Boolean betulkah = true;
            for (String tes : valueFromBitSet) {
                //System.out.println(temp.get(j)+"   "+tes+"   "+tes.equalsIgnoreCase(temp.get(j)));
                if (!tes.isEmpty() && tes.equalsIgnoreCase(temp.get(j))) {
                    
                } else if (!tes.isEmpty()) {
                    betulkah = false;
                }
                j++;
            }
            if (betulkah) {
                jumlah++;
                //System.out.println("betul indeks ke "+i);
            }
            //System.out.println("");
        }
        
        return jumlah;
    }
    
    Vector<String> getDataValue(int idx) {
        Map<String, Object> mp = arrayData.get(idx);
        Vector<String> ret = new Vector<String>();
        for (Map.Entry<String, Object> mEntry : mp.entrySet()) {
            ret.add((String)mEntry.getValue());
        }
        return ret;
    }
    
    public static int bitStringToInt(String bitS) {
        int bitInteger = 0;
        for(int i = 0 ; i < bitS.length(); i++) {
            if(bitS.charAt(i)=='1')
                bitInteger |= (1 << (bitS.length()-i-1));
        }
        return bitInteger;
    }
    
    public static String intToBitString(int val, int jumlahBit) {
        return String.format("%"+jumlahBit+"s", Integer.toBinaryString(val)).replace(' ', '0');
    }
    
    
    
    public static int bitSetToInt(BitSet bitSet, int max)
    {
        int bitInteger = 0;
        for(int i = 0 ; i < max; i++) {
            if(bitSet.get(i))
                bitInteger |= (1 << (max-i-1));
        }
        return bitInteger;
    }
    
    public static BitSet intToBitSet(int a, int max) {
        BitSet ret = new BitSet(max);
        if (a!=0) {
            int value = a;
            for(int i = 0; i < max; i++)
                if ((value & (1<<i))>0)
                    ret.set(max-i-1);
        }
        return ret;
    }
    
    @Override
    public String toString() {
        StringBuilder ret=new StringBuilder();
        Iterator iter = arrayData.iterator();
        while (iter.hasNext()) {
            Map<String, Object> mp = (Map<String, Object>) iter.next();
            for (Map.Entry<String, Object> mEntry : mp.entrySet()) {
                ret.append(mEntry.getValue().toString());
                ret.append("    ");
            }
            if (iter.hasNext())
                ret.append("\n");
        }
        return ret.toString();
    }
    
}
